﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Drawing.Printing;

namespace SoftLab.Reportes
{
    public class Report
    {
        public string Impresora {get; set;}
        public string Prueba { get; set; }

        private PrintDocument _pd = new PrintDocument();
        private readonly List<String> _titulo = new List<string>();
        private readonly List<String> _subtituloIzquierda = new List<string>();
        private readonly List<Items> _items = new List<Items>();
        private readonly List<String> _pie = new List<string>();
        private Font _font = new Font("Segoe UI", 14);
        private readonly SolidBrush _brush  = new SolidBrush(Color.Black);
        private Graphics _g;

        private const int Left = 5;
        private const int Top = 5;
        private const int Right = 5;
        private int _count;
        
        public Report(string impresora)
        {
            Impresora = impresora;
        }

        public void AgregarTítulo(string texto)
        {
            _titulo.Add(texto);
        }

        public void AgregarSubtitulo(string texto)
        {
            _subtituloIzquierda.Add(texto);
        }

        public void AgregarItem(Items items)
        {
            _items.Add(items);
        }

        public void AgregarPie(string texto)
        {
            _pie.Add(texto);
        }

        public void Imprimir()
        {
            if (String.IsNullOrWhiteSpace(Impresora))
                // ReSharper disable once NotResolvedInText
                throw new ArgumentNullException("Impresora no encontrada o incluida.");
            _pd.PrinterSettings.PrinterName = Impresora;
            _pd.PrintPage += PdPrintPage;
            _pd.Print();
        }

        private void PdPrintPage(object sender, PrintPageEventArgs e)
        {
            _g = e.Graphics;
            PrintTimeAndDate(_g);
            PrintHeader(_g);
            PrintSpace(_g);
            PrintSubHeader(_g);
            PrintLine(_g);
            PrintItem(_g);
            PrintLine(_g);
            PrintFooter(_g);
        }

        private float YPosition()
        {
            return Top + (_count * _font.GetHeight(_g));
        }

        void PrintSpace(Graphics g)
        {
            g.DrawString("", _font, _brush, Left, YPosition());
            _count++;
        }

        void PrintTimeAndDate(Graphics g)
        {
            var date = DateTime.Today.ToShortDateString();
            _font = new Font("Segoe UI", 10, FontStyle.Bold);
            var font = new Font("Free 3 of 9", 20);
            g.DrawString("*" + Prueba + "*", font, _brush, Left, YPosition());
            g.DrawString(date, _font, _brush, Left+730, YPosition());
            _count++;
        }

        void PrintHeader(Graphics g)
        {
            foreach (var t in _titulo)
            {
                _font = new Font("Segoe UI", 16, FontStyle.Bold);
                g.DrawString(t, _font, _brush, Left, YPosition());
                _count++;
            }
        }

        void PrintSubHeader(Graphics g)
        {
            foreach (var t in _subtituloIzquierda)
            {
                _font = new Font("Segoe UI", 14, FontStyle.Italic);
                g.DrawString(t, _font, _brush, Left, YPosition());
                _count++;
            }
        }

        void PrintLine(Graphics g)
        {
            _font = new Font("Segoe UI", 14, FontStyle.Italic);
            string dot = "";
            for (int i = Left; i < 108; i++)
            {
                dot += "-";
            }
            g.DrawString(dot, _font, _brush, Left, YPosition());
            _count++;
        }

        void PrintItem(Graphics g)
        {
            _font = new Font("Segoe UI", 12, FontStyle.Bold);
            const string titulos = "EXAMEN                                                  RESULTADO                         VALOR NORMAL";
            g.DrawString("", _font, _brush, Left, YPosition());
            _count++;
            g.DrawString("", _font, _brush, Left, YPosition());
            _count++;
            g.DrawString(titulos, _font, _brush, Left, YPosition());
            _count+= 2;
            _font = new Font("Segoe UI", 12, FontStyle.Regular);
            foreach (var t in _items)
            {
                var b = new StringBuilder();
                //b.Append(t.Nombre);
                //var examen = 57 - t.Nombre.Length;
                //if (examen > 0)
                //    for (int i = 1; i <= examen; i++)
                //        b.Append(" ");
                //b.Append(t.Resultado);
                //var resultado = 39 - t.Resultado.Length;
                //if (resultado > 0)
                //    for (int i = 1; i <= resultado; i++)
                //        b.Append(" ");
                //b.Append(t.ValorNormal);
                //b.Append(string.Format("{0, 57}", t.Nombre));
                //b.Append(string.Format("{0, 39}", t.Resultado));
                //b.Append(string.Format("{0, 20}", t.ValorNormal));
                var texto = String.Format("{0, -57} - {1, -35} - {2, -35}", t.Nombre, t.Resultado, t.ValorNormal);
                g.DrawString(texto, _font, _brush, Left, YPosition());
                _count++;
            }
        }

        void PrintFooter(Graphics g)
        {
            g.DrawString("", _font, _brush, Left, YPosition());
            _count++;
            foreach (var p in _pie)
            {
                g.DrawString(p, _font, _brush, Left, YPosition());
                _count++;
            }
        }
    }

    public struct Items
    {
        public string Nombre { get; set; }
        public string Resultado { get; set; }
        public string ValorNormal { get; set; }
    }
}
